#include <iostream>
#include <functional>
#include <memory>
#include "Log.hpp"
#include "TcpServer.hpp"  // 处理IO的
#include "Calculator.hpp" // 处理业务的

// 本demo业务逻辑比较简单 如果有特别耗时的操作 收到的数据不一定是完整的数据
Calculator calculator;

// weak_ptr只可以从一个shared_ptr或另一个weak_ptr对象构造
// 它的构造和析构不会引起引用记数的增加或减少
void DefaultOnMessage(std::weak_ptr<TcpConnection> connectionWeakPtr)
{
    // 判断当前weak_ptr智能指针是否 过期/还有托管的对象
    // expired() == true 即use_count() == 0 即已经没有托管的对象了 即过期了
    // 可能还有析构函数进行释放内存 但此对象的析构已经临近或可能已发生
    if (connectionWeakPtr.expired())
        return;
    // 转为shared_ptr
    auto connSharedPtr = connectionWeakPtr.lock();

    // 0. 将数据从接收缓冲区中取出来
    std::string inbuffer = connSharedPtr->getInbuffer();
    // 1.删除接收缓冲区中已经读取的数据 
    connSharedPtr->ClearInBuffer();
    // 2.echo 客户端发来的数据
    std::cout << "==============client send and server recved=============" << std::endl;
    std::cout << inbuffer;
    std::cout << "==============client send and server recved=============" << std::endl;
    // 3.将数据交给业务层处理
    std::string response_str = calculator.Handler(inbuffer);
    if (response_str.empty())
        return;
    std::cout << "============server response===========" << std::endl;
    std::cout << response_str;
    std::cout << "============server response===========" << std::endl;

    // 将处理好的数据拷贝到发送缓冲区
    connSharedPtr->AppendOutBuffer(response_str);
    auto tcpSvr_SharedPtr = connSharedPtr->_tcpSvr_weakPtr.lock();
    tcpSvr_SharedPtr->Sender(connSharedPtr);
}

int main()
{
    std::shared_ptr<TcpServer> epollTcpSvr_SharedPtr(new TcpServer(8888, DefaultOnMessage));
    epollTcpSvr_SharedPtr->Init();
    epollTcpSvr_SharedPtr->Loop();

    return 0;
}
